package com.doraro.platform.module.user.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.exceptions.ApiException;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.doraro.platform.common.exception.ApiGlobalException;
import com.doraro.platform.common.utils.Constant;
import com.doraro.platform.common.utils.EncryptUtil;
import com.doraro.platform.common.utils.HttpContextUtils;
import com.doraro.platform.module.user.mapper.SysUserMapper;
import com.doraro.platform.module.user.model.dto.UserDetail;
import com.doraro.platform.module.user.model.entity.SysRole;
import com.doraro.platform.module.user.model.entity.SysUser;
import com.doraro.platform.module.user.model.entity.SysUserRole;
import com.doraro.platform.module.user.model.vo.SysUserParam;
import com.doraro.platform.module.user.service.ISysRoleService;
import com.doraro.platform.module.user.service.ISysUserRoleService;
import com.doraro.platform.module.user.service.ISysUserService;
import org.apache.commons.lang3.RandomStringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.servlet.http.HttpServletRequest;
import java.io.Serializable;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;
import java.util.Set;

/**
 * <p>
 * 服务实现类
 * </p>
 *
 * @author doraro
 * @since 2019-04-21
 */
@Service
public class SysUserServiceImpl extends ServiceImpl<SysUserMapper, SysUser> implements ISysUserService {
    private final ISysUserRoleService userRoleService;
    private final ISysRoleService roleService;

    @Autowired
    public SysUserServiceImpl(ISysUserRoleService userRoleService, ISysRoleService roleService) {
        this.userRoleService = userRoleService;
        this.roleService = roleService;
    }

    @Override
    public SysUser getById(Serializable id) {
        return super.getById(id);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public SysUser login(SysUserParam user, HttpServletRequest request) {
        final SysUser sysUser = this.getUserByName(user.getLoginName());
        if (sysUser == null) {
            throw new ApiGlobalException(400, "用户名或密码错误");
        }
        final String salt = sysUser.getSalt();
        String encode = EncryptUtil.getSha512(salt + ":" + user.getPassword());
        if (!encode.equals(sysUser.getPassword())) {
            throw new ApiGlobalException(400, "用户名或密码错误");
        }
        //更新last login time,ip
        super.lambdaUpdate()
                .set(SysUser::getLastLoginTime, LocalDateTime.now())
                .set(SysUser::getIp, HttpContextUtils.getIpAddr(request))
                .eq(SysUser::getId, sysUser.getId())
                .update();
        return sysUser;
    }

    @Override
    public SysUser getUserByName(String username) {
        return super.getOne(new QueryWrapper<SysUser>().lambda()
                .eq(SysUser::getLoginName, username));
    }

    /**
     * 可能需要邮箱验证后，由管理员分配角色而不是直接分配角色
     * 不允许注册为管理员
     * @param param
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void register(SysUserParam param) {
        final Integer roleId = param.getRoleId();
        final SysRole role = roleService.getById(roleId);
        //不允许注册为管理员
        if (role == null || Constant.ADMIN_NAME.equals(role.getName())) {
            throw new ApiException("用户角色类型错误!");
        }
        final String password = param.getPassword();
        String salt = RandomStringUtils.randomAlphabetic(36);
        String encode = EncryptUtil.getSha512(salt + ":" + password);
        final SysUser user = param.convert(SysUser.class);
        user.setCreateTime(LocalDateTime.now());
        user.setUpdateTime(LocalDateTime.now());
        user.setPassword(encode);
        user.setSalt(salt);
        user.setUserStatus(1);
        super.save(user);
        userRoleService.save(new SysUserRole().setRoleId(roleId).setUid(user.getId()));

    }



    /**
     * TODO:获取未读消息
     *
     * @param userId
     * @return
     */
    @Override
    public UserDetail getUserDetail(String userId) {
        final SysUser user = this.getById(userId);
        if (user == null) {
            throw new ApiGlobalException("不存在用户");
        }
        final UserDetail userDetail = user.convert(UserDetail.class);
        final List<SysRole> roles = roleService.getRolesByUserId(userId);
        List<Integer> rIds = new ArrayList<>();
        List<String> rNames = new ArrayList<>();
        for (SysRole role : roles) {
            rIds.add(role.getId());
            rNames.add(role.getName());
        }
        userDetail.setRoleList(rNames);
        final Set<String> perms = roleService.getPemsByRoleIds(rIds);
        userDetail.setPermList(perms);
        return userDetail;
    }


}
